package com.zsp.utils.security_jwt;

import io.jsonwebtoken.Claims;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtUtil jwtUtil;

    // 构造函数注入 JwtUtil 工具类
    public JwtAuthenticationFilter(JwtUtil jwtUtil) {
        this.jwtUtil = jwtUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws java.io.IOException, javax.servlet.ServletException {

        String token = request.getHeader("Authorization"); // 从请求头中获取 Token
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7); // 去掉 "Bearer " 前缀
            try {
                Claims claims = jwtUtil.extractClaims(token); // 验证 Token 并提取 Claims
                String data = claims.getSubject(); // 获取用户 ID（或其他主体信息）
//                // Step 1: 创建 Jackson 的 ObjectMapper 对象，用于解析 JSON 数据
//                ObjectMapper objectMapper = new ObjectMapper();
//                // Step 2: 将 JSON 字符串解析为 JsonNode 树结构
//                JsonNode rootNode = objectMapper.readTree(data);
//                // Step 3: 从 JsonNode 树中提取属性 'id' 的值
//                JsonNode idNode = rootNode.path("id"); // 使用 `path()` 方法获取键 'id' 的子节点
//                String userId = idNode.asText(); // 转换为字符串（如果键不存在，返回空字符串）
                // 创建并设置当前用户的认证信息
                User authenticatedUser = new User(data, "", new ArrayList<>()); // 空权限列表
                SecurityContextHolder.getContext().setAuthentication(
                        new JwtAuthentication(authenticatedUser, claims)); // 设置认证信息
                // 将用户的认证信息保存到 Spring Security 的安全上下文（SecurityContextHolder）中。
                // 这个存储是线程安全的，后续的业务代码可以通过 SecurityContextHolder 获取当前用户身份。写在了SecurityUtils里面
            } catch (Exception e) {
                // Token 验证失败（可打印日志或返回错误响应）
                SecurityContextHolder.clearContext();
            }
        }

        // 放行过滤器链，继续后续处理
        filterChain.doFilter(request, response);
    }
}
